<?php
namespace App\Repositories;

use App\Models\Message;
use App\Models\Quiz;
use Carbon\Carbon;

class MessageRepository
{
    const MESSAGE_STATUS_WAIT_SEND = 1;
    const MESSAGE_STATUS_HAS_SEND = 2;
    const MESSAGE_STATUS_CANCELED = 0;

    /**
     * @var array 可以发送消息时间段
     */
    public static $canSendingTime = ['09:00:00', '22:00:00'];

    /**
     * 发送模板消息
     *
     * @param Quiz $quiz
     * @param $formId
     */
    public static function sendCreateQuizMessage(Quiz $quiz, $formId)
    {
        $message = new Message();
        $key = self::makeMessageKey($quiz);
        $sendAt = self::forceInCanSendingTime(string_to_datetime($quiz->stop_at));

        $message->fill([
            'key' => $key,
            'user_id' => $quiz->user_id,
            'value' => json_encode(['name' => $quiz->name, 'id' => $quiz->id]),
            'send_at' => $sendAt,
            'status' => self::MESSAGE_STATUS_WAIT_SEND,
            'form_id' => $formId,
        ]);
        $message->save();
        \App\Jobs\SendTemplateMessage::dispatch($key)->delay($sendAt);
    }

    /**
     * 只有在规定的时间内才发送消息
     *
     * @param Carbon $datetime
     * @return Carbon
     */
    public static function forceInCanSendingTime(Carbon $datetime)
    {
        $beginDatetime = $datetime->copy()->setTimeFromTimeString(self::$canSendingTime[0]);
        $endDatetime = $datetime->copy()->setTimeFromTimeString(self::$canSendingTime[1]);
        if ($datetime < $beginDatetime) {
            $datetime = $beginDatetime;
        } elseif ($datetime > $endDatetime) {
            $datetime = $beginDatetime->addDay(1);
        }
        return $datetime;
    }

    /**
     * 取消发送模板消息
     *
     * @param Quiz $quiz
     */
    public static function cancelSendMessage(Quiz $quiz)
    {
        $key = self::makeMessageKey($quiz);

        self::getMessageByKeyQuery($key)->update([
            'status' => self::MESSAGE_STATUS_CANCELED
        ]);
    }

    /**
     * @param $key
     * @return mixed
     */
    public static function getMessageByKeyQuery($key)
    {
        return Message::where('key', $key)
            ->where('status', self::MESSAGE_STATUS_WAIT_SEND);
    }

    /**
     * @param $key
     * @return Message
     */
    public static function findMessageByKey($key)
    {
        return self::getMessageByKeyQuery($key)->first();
    }

    /**
     * @param $model
     * @return string
     */
    protected static function makeMessageKey($model)
    {
        return sprintf(str_replace('\\', '_', get_class($model)).'_%s', $model->id);
    }
}